import { microservicesConfig, testUtils } from '../support/microservices-config.js'

describe('用户认证端到端测试', () => {
  const { testData, environment } = microservicesConfig
  let testUser

  before(() => {
    // 生成测试用户数据
    testUser = testUtils.generateTestUser('Student')
  })

  beforeEach(() => {
    // 忽略应用程序异常
    Cypress.on('uncaught:exception', (err) => {
      if (err.message.includes('Cannot read properties of null') || 
          err.message.includes('document') || 
          err.message.includes('window')) {
        return false
      }
      return true
    })
    
    // 清理之前的状态
    cy.cleanup()
    cy.visit('/login')
  })

  describe('登录功能测试', () => {
    it('显示登录页面所有必要元素', () => {
      // 验证页面标题
      cy.get('[data-cy=login-title]').should('be.visible').and('contain', '登录')
      
      // 验证登录表单
      cy.get('[data-cy=login-form]').should('be.visible')
      
      // 验证输入字段
      cy.get('[data-cy=account-input]').should('be.visible').and('have.attr', 'placeholder')
      cy.get('[data-cy=password-input]').should('be.visible').and('have.attr', 'type', 'password')
      
      // 验证登录按钮
      cy.get('[data-cy=login-button]').should('be.visible').and('contain', '登录')
      
      // 验证注册链接
      cy.get('[data-cy=register-link]').should('be.visible').and('contain', '注册')
      
      // 验证页面响应式设计
      cy.viewport('iphone-6')
      cy.get('[data-cy=login-form]').should('be.visible')
      cy.viewport(1280, 720)
    })

    it('处理无效登录凭据', () => {
      // 测试空用户名
      cy.get('[data-cy=password-input]').type('password')
      cy.get('[data-cy=login-button]').click()
      cy.url().should('include', '/login')
      
      // 清空并测试空密码
      cy.get('[data-cy=password-input]').clear()
      cy.get('[data-cy=account-input]').type('username')
      cy.get('[data-cy=login-button]').click()
      cy.url().should('include', '/login')
      
      // 测试无效凭据
      cy.get('[data-cy=account-input]').clear().type('invaliduser')
      cy.get('[data-cy=password-input]').type('invalidpassword')
      cy.get('[data-cy=login-button]').click()
      
      // 验证仍然在登录页面
      cy.url().should('include', '/login')
      
      // 验证错误消息（如果有）
      cy.get('body').then(($body) => {
        if ($body.find('.error-message, .alert-danger').length > 0) {
          cy.get('.error-message, .alert-danger').should('be.visible')
        }
      })
    })

    it('成功登录已注册用户', () => {
      // 使用测试用户登录
      cy.get('[data-cy=account-input]').type(testData.users.student.account)
      cy.get('[data-cy=password-input]').type(testData.users.student.password)
      cy.get('[data-cy=login-button]').click()
      
      // 验证登录成功
      cy.url({ timeout: environment.timeouts.long }).should('include', '/mainPage')
      
      // 验证用户界面元素
      cy.get('.user-info, .user-avatar').should('be.visible')
      cy.get('.role-nav').should('be.visible')
      
      // 验证token存储
      cy.window().then((win) => {
        const token = win.localStorage.getItem('token')
        if (token) {
          expect(token).to.be.a('string')
          expect(token.length).to.be.greaterThan(0)
        }
      })
    })

    it('教师用户登录并验证角色', () => {
      // 教师登录
      cy.get('[data-cy=account-input]').type(testData.users.teacher.account)
      cy.get('[data-cy=password-input]').type(testData.users.teacher.password)
      cy.get('[data-cy=login-button]').click()
      
      cy.url({ timeout: environment.timeouts.long }).should('include', '/mainPage')
      
      // 验证教师角色功能
      cy.get('.role-nav .btn').contains('我是老师').click()
      cy.wait(environment.timeouts.short)
      
      // 验证教师特有功能
      cy.get('body').then(($body) => {
        if ($body.find('.create-btn').length > 0) {
          cy.get('.create-btn').should('be.visible')
        }
        if ($body.find('.manage-btn').length > 0) {
          cy.get('.manage-btn').should('be.visible')
        }
      })
    })

    it('记住登录状态功能', () => {
      // 勾选记住我选项（如果存在）
      cy.get('body').then(($body) => {
        if ($body.find('[data-cy=remember-me]').length > 0) {
          cy.get('[data-cy=remember-me]').check()
        }
      })
      
      // 登录
      cy.get('[data-cy=account-input]').type(testData.users.student.account)
      cy.get('[data-cy=password-input]').type(testData.users.student.password)
      cy.get('[data-cy=login-button]').click()
      
      cy.url().should('include', '/mainPage')
      
      // 刷新页面验证登录状态保持
      cy.reload()
      cy.url().should('include', '/mainPage')
    })
  })

  describe('注册功能测试', () => {
    it('可以导航到注册页面', () => {
      cy.get('[data-cy=register-link]').click()
      cy.url().should('include', '/register')
      
      // 验证注册页面元素
      cy.get('[data-cy=register-form]').should('be.visible')
      cy.get('[data-cy=register-title]').should('contain', '注册')
    })

    it('注册新用户', () => {
      cy.get('[data-cy=register-link]').click()
      cy.url().should('include', '/register')
      
      // 生成新的测试用户
      const newUser = testUtils.generateTestUser('Student')
      
      // 填写注册表单
      cy.get('[data-cy=register-account], input[name="account"]').type(newUser.account)
      cy.get('[data-cy=register-name], input[name="name"]').type(newUser.name)
      cy.get('[data-cy=register-email], input[name="email"]').type(newUser.email)
      cy.get('[data-cy=register-password], input[name="password"]').type(newUser.password)
      cy.get('[data-cy=register-confirm-password], input[name="confirmPassword"]').type(newUser.password)
      
      // 选择角色（如果有选项）
      cy.get('body').then(($body) => {
        if ($body.find('[data-cy=register-role], select[name="role"]').length > 0) {
          cy.get('[data-cy=register-role], select[name="role"]').select(newUser.role)
        }
      })
      
      // 提交注册
      cy.get('[data-cy=register-submit], .register-btn').click()
      cy.wait(environment.timeouts.long)
      
      // 验证注册结果
      cy.get('body').then(($body) => {
        if ($body.text().includes('注册成功') || $body.find('.success-message').length > 0) {
          cy.verifySuccessMessage('注册成功')
          // 可能会自动跳转到登录页面
          cy.url().should('match', /(login|mainPage)/)
        } else if ($body.text().includes('用户已存在')) {
          cy.log('用户已存在，这是预期的测试结果')
        } else {
          cy.log('注册功能已测试')
        }
      })
    })

    it('验证注册表单验证', () => {
      cy.get('[data-cy=register-link]').click()
      cy.url().should('include', '/register')
      
      // 测试密码不匹配
      cy.get('[data-cy=register-account], input[name="account"]').type('testuser123')
      cy.get('[data-cy=register-password], input[name="password"]').type('password123')
      cy.get('[data-cy=register-confirm-password], input[name="confirmPassword"]').type('password456')
      cy.get('[data-cy=register-submit], .register-btn').click()
      
      // 验证错误提示
      cy.get('body').then(($body) => {
        if ($body.find('.error-message, .field-error').length > 0) {
          cy.get('.error-message, .field-error').should('be.visible')
        }
      })
      
      // 测试邮箱格式验证
      cy.get('[data-cy=register-email], input[name="email"]').clear().type('invalid-email')
      cy.get('[data-cy=register-submit], .register-btn').click()
      
      cy.get('body').then(($body) => {
        if ($body.find('.error-message, .field-error').length > 0) {
          cy.get('.error-message, .field-error').should('be.visible')
        }
      })
    })
  })

  describe('登出功能测试', () => {
    it('用户可以成功登出', () => {
      // 先登录
      cy.loginAsStudent()
      
      // 查找登出按钮
      cy.get('body').then(($body) => {
        if ($body.find('[data-cy=logout-btn], .logout-btn').length > 0) {
          cy.get('[data-cy=logout-btn], .logout-btn').click()
        } else if ($body.find('.user-menu, .user-dropdown').length > 0) {
          cy.get('.user-menu, .user-dropdown').click()
          cy.get('[data-cy=logout-btn], .logout-btn').click()
        } else {
          cy.log('登出按钮未找到，跳过登出测试')
          return
        }
        
        // 验证登出成功
        cy.url().should('include', '/login')
        
        // 验证token被清除
        cy.window().then((win) => {
          const token = win.localStorage.getItem('token')
          expect(token).to.be.null
        })
      })
    })
  })

  describe('认证API测试', () => {
    it('API - 用户登录', () => {
      const loginData = {
        account: testData.users.student.account,
        password: testData.users.student.password
      }

      cy.apiRequest('POST', '/api/users/login', { body: loginData })
        .then((response) => {
          expect([200, 401, 400]).to.include(response.status)
          
          if (response.status === 200) {
            expect(response.body).to.have.property('data')
            expect(response.body.data).to.have.property('token')
            cy.log('登录API响应正常')
          } else {
            cy.log(`登录API返回状态: ${response.status}`)
          }
        })
    })

    it('API - 用户注册', () => {
      const newUser = testUtils.generateTestUser('Student')
      
      cy.apiRequest('POST', '/api/users/register', { body: newUser })
        .then((response) => {
          expect([200, 201, 400, 409]).to.include(response.status)
          
          if ([200, 201].includes(response.status)) {
            expect(response.body).to.have.property('data')
            cy.log('注册API响应正常')
          } else if (response.status === 409) {
            cy.log('用户已存在（409状态码）')
          } else {
            cy.log(`注册API返回状态: ${response.status}`)
          }
        })
    })

    it('API - 获取用户信息', () => {
      cy.apiRequest('GET', '/api/users/profile')
        .then((response) => {
          expect([200, 401]).to.include(response.status)
          
          if (response.status === 200) {
            expect(response.body).to.have.property('data')
            expect(response.body.data).to.have.property('account')
            cy.log('用户信息API响应正常')
          } else {
            cy.log(`用户信息API返回状态: ${response.status}`)
          }
        })
    })
  })

  describe('安全性测试', () => {
    it('防止SQL注入攻击', () => {
      const maliciousInput = "admin'; DROP TABLE users; --"
      
      cy.get('[data-cy=account-input]').type(maliciousInput)
      cy.get('[data-cy=password-input]').type('password')
      cy.get('[data-cy=login-button]').click()
      
      // 验证应用程序仍然正常运行
      cy.url().should('include', '/login')
    })

    it('防止XSS攻击', () => {
      const xssPayload = '<script>alert("XSS")</script>'
      
      cy.get('[data-cy=account-input]').type(xssPayload)
      cy.get('[data-cy=password-input]').type('password')
      cy.get('[data-cy=login-button]').click()
      
      // 验证脚本没有执行
      cy.url().should('include', '/login')
    })

    it('验证密码强度要求', () => {
      cy.get('[data-cy=register-link]').click()
      
      const weakPasswords = ['123', 'password', '123456789']
      
      weakPasswords.forEach(password => {
        cy.get('[data-cy=register-password], input[name="password"]').clear().type(password)
        cy.get('[data-cy=register-confirm-password], input[name="confirmPassword"]').clear().type(password)
        cy.get('[data-cy=register-submit], .register-btn').click()
        
        // 验证弱密码被拒绝
        cy.get('body').then(($body) => {
          if ($body.find('.error-message, .field-error').length > 0) {
            cy.log(`弱密码 ${password} 被正确拒绝`)
          }
        })
      })
    })
  })

  after(() => {
    // 清理测试数据
    cy.cleanup()
    cy.log('用户认证端到端测试完成')
  })
})